package com.pan.admin.module.market.service.impl;

import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.valid.Assert;
import com.gitee.apanlh.util.valid.ValidParam;
import com.pan.admin.cache.DistrictCache;
import com.pan.admin.common.annotation.DataSource;
import com.pan.admin.common.enums.DataSourceType;
import com.pan.admin.common.utils.DateUtils;
import com.pan.admin.common.utils.SecurityUtils;
import com.pan.admin.module.channel.dao.LoanChannelDao;
import com.pan.admin.module.channel.dao.LoanChannelMarketDao;
import com.pan.admin.module.channel.entity.LoanChannel;
import com.pan.admin.module.channel.entity.LoanChannelMarket;
import com.pan.admin.module.common.entity.DistrictPO;
import com.pan.admin.module.market.dao.LoanMarketDao;
import com.pan.admin.module.market.dao.LoanMarketFilterAreaDao;
import com.pan.admin.module.market.entity.LoanMarket;
import com.pan.admin.module.market.entity.po.LoanMarketFilterAreaPO;
import com.pan.admin.module.market.service.LoanMarketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


/**
 * 贷款超市Service业务层处理
 *
 * @author ts
 * @date 2023-09-13
 */
@Service
public class LoanMarketServiceImpl implements LoanMarketService {

    @Autowired
    private LoanMarketDao loanMarketDao;
    @Autowired
    private LoanChannelDao loanChannelDao;
    @Autowired
    private LoanMarketFilterAreaDao loanMarketFilterAreaDao;
    @Autowired
    private LoanChannelMarketDao loanChannelMarketDao;

    @Override
    @Transactional(readOnly = true)
    public List<LoanMarket> list(LoanMarket loanMarket) {
        return loanMarketDao.list(loanMarket);
    }

    @Override
    @Transactional(readOnly = true)
    @DataSource(DataSourceType.SLAVE)
    public List<LoanMarket> listSlave(LoanMarket loanMarket) {
        return loanMarketDao.list(loanMarket);
    }

    /**
     * 根据ID获取列表贷款超市
     *
     * @param id 贷款超市主键
     * @return 贷款超市
     */
    @Override
    @Transactional(readOnly = true)
    public LoanMarket getById(Long id) {
        LoanMarket loanMarket = loanMarketDao.getById(id);

        //  获取关联屏蔽地区数据
        LoanMarketFilterAreaPO loanMarketFilterAreaPO = new LoanMarketFilterAreaPO();
        loanMarketFilterAreaPO.setLoanMarketId(loanMarket.getId());
        List<LoanMarketFilterAreaPO> list = loanMarketFilterAreaDao.list(loanMarketFilterAreaPO);

        //  改变原有pCode值,县级市合并为市级
        List<String> areas = CollUtils.newArrayList(newList -> {
            List<String> areaCodes = CollUtils.toList(list, t -> t.getAreaCode());
            IteratorUtils.array(areaCodes, t -> newList.add(t.substring(0, 2) + "0000" + "," + t));
        });
        loanMarket.setAreas(areas);

        return loanMarket;
    }


    /**
     * 新增贷款超市
     *
     * @param loanMarket 贷款超市
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertLoanMarket(LoanMarket loanMarket) {
        int row;

        //  新增贷超
        loanMarket.setCreateTime(DateUtils.getNowDate());
        loanMarket.setCreateBy(SecurityUtils.getUsername());
        row = loanMarketDao.insertLoanMarket(loanMarket);

        //  新增贷超关联渠道
        Integer channelProductState = loanMarket.getChannelProductState();
        if (ValidParam.isNotNull(channelProductState)) {
            List<Long> ids = CollUtils.newArrayList();

            // 关联渠道-全选
            if (channelProductState == 0) {
                LoanChannel loanChannel = new LoanChannel();
                loanChannel.setSelectApiChannel(false);
                ids.addAll(CollUtils.toList(loanChannelDao.list(loanChannel), t -> t.getId()));
            }

            // 关联渠道-自定义
            if (channelProductState == 1) {
                ids.addAll(loanMarket.getOptionsSelected());
            }

            List<LoanChannelMarket> marketList = CollUtils.newArrayList();
            if (ValidParam.isNotEmpty(ids)) {
                for (Long channelId : ids) {
                    LoanChannelMarket channelProduct = new LoanChannelMarket();
                    channelProduct.setCreateTime(DateUtils.getNowDate());
                    channelProduct.setLoanChannelId(channelId);
                    channelProduct.setLoanMarketId(loanMarket.getId());
                    channelProduct.setStatus(1);
                    channelProduct.setCreateBy(SecurityUtils.getUsername());
                    marketList.add(channelProduct);
                }
                row = loanChannelMarketDao.batchInsert(marketList);
            }
        }

        //  关联指定地区
        List<String> areas = loanMarket.getAreas();
        if (ValidParam.isNotEmpty(areas)) {
            List<LoanMarketFilterAreaPO> list = CollUtils.newArrayList();
            Long id = loanMarket.getId();

            for (String area: areas) {
                DistrictPO districtPO = DistrictCache.getByCode(area);
                Assert.isNotNullThrows(districtPO, new RuntimeException("错误地区"));

                LoanMarketFilterAreaPO loanMarketFilterAreaPO = new LoanMarketFilterAreaPO();
                loanMarketFilterAreaPO.setLoanMarketId(id);
                loanMarketFilterAreaPO.setAreaName(districtPO.getName());
                loanMarketFilterAreaPO.setAreaCode(districtPO.getCode());
                loanMarketFilterAreaPO.setCreateTime(DateUtils.getNowDate());
                loanMarketFilterAreaPO.setCreateBy(SecurityUtils.getUsername());
                list.add(loanMarketFilterAreaPO);
            }
            loanMarketFilterAreaDao.batchInsert(list);
        }

        //  获取所有可选择渠道
        LoanChannel enableChannel = new LoanChannel();
        enableChannel.setSelectApiChannel(false);
        enableChannel.setStatus(1);
        List<LoanChannel> listChannel = loanChannelDao.list(enableChannel);

        //  关联已选择屏蔽的渠道
        List<Long> listSelectFilterChannelId = loanMarket.getListSelectFilterChannelId();
        //  筛选最终关联的渠道
        CollUtils.filter(listChannel, t -> {
            Long findId = CollUtils.findOne(listSelectFilterChannelId, selectId -> t.getId().equals(selectId));
            return ValidParam.isNotNull(findId);
        });

        //  插入渠道贷超数据
        if (ValidParam.isNotEmpty(listChannel)) {
            List<LoanChannelMarket> listChannelMarket = CollUtils.newArrayList();
            IteratorUtils.array(listChannel, t -> {
                LoanChannelMarket loanChannelMarket = new LoanChannelMarket();
                loanChannelMarket.setLoanChannelId(t.getId());
                loanChannelMarket.setLoanMarketId(loanMarket.getId());
                loanChannelMarket.setStatus(1);
                loanChannelMarket.setCreateTime(DateUtils.getNowDate());
                loanChannelMarket.setCreateBy(SecurityUtils.getUsername());
                listChannelMarket.add(loanChannelMarket);
            });
            loanChannelMarketDao.batchInsert(listChannelMarket);
        }

        if (row < 1) {
            throw new RuntimeException("回滚");
        }
        return row;
    }

    /**
     * 修改贷款超市
     *
     * @param loanMarket 贷款超市
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateLoanMarket(LoanMarket loanMarket) {
        loanMarket.setUpdateTime(DateUtils.getNowDate());
        loanMarket.setUpdateBy(SecurityUtils.getUsername());

        //  更新贷超
        int i = loanMarketDao.updateLoanMarket(loanMarket);

        //  更新地区
        List<String> areas = loanMarket.getAreas();
        //  删除原有地区
        loanMarketFilterAreaDao.deleteByMarketId(loanMarket.getId());
        //  关联指定地区
        if (ValidParam.isNotEmpty(areas)) {
            List<LoanMarketFilterAreaPO> list = CollUtils.newArrayList();
            Long id = loanMarket.getId();

            for (String area: areas) {
                DistrictPO districtPO = DistrictCache.getByCode(area);
                Assert.isNotNullThrows(districtPO, new RuntimeException("错误地区"));

                LoanMarketFilterAreaPO loanMarketFilterAreaPO = new LoanMarketFilterAreaPO();
                loanMarketFilterAreaPO.setLoanMarketId(id);
                loanMarketFilterAreaPO.setAreaName(districtPO.getName());
                loanMarketFilterAreaPO.setAreaCode(districtPO.getCode());
                loanMarketFilterAreaPO.setCreateTime(DateUtils.getNowDate());
                loanMarketFilterAreaPO.setCreateBy(SecurityUtils.getUsername());
                list.add(loanMarketFilterAreaPO);
            }
            loanMarketFilterAreaDao.batchInsert(list);
        }

        //  更新屏蔽渠道
        List<Long> listSelectFilterChannelId = loanMarket.getListSelectFilterChannelId();

        //  获取所有可选择渠道
        LoanChannel enableChannel = new LoanChannel();
        enableChannel.setSelectApiChannel(false);
        enableChannel.setStatus(1);
        List<LoanChannel> listChannel = loanChannelDao.list(enableChannel);

        //  获取关联数据
        LoanChannelMarket loanChannelMarketQO = new LoanChannelMarket();
        loanChannelMarketQO.setLoanMarketId(loanMarket.getId());
        List<LoanChannelMarket> loanChannelMarketList = loanChannelMarketDao.list(loanChannelMarketQO);

        if (ValidParam.isNotEmpty(listChannel)) {
            IteratorUtils.array(listChannel, t -> {
                Long findId = CollUtils.findOne(listSelectFilterChannelId, selectId -> t.getId().equals(selectId));
                Integer status = ValidParam.isNotNull(findId) ? 0 : 1;

                LoanChannelMarket findLoanChannelMarket = CollUtils.findOne(loanChannelMarketList, item -> t.getId().equals(item.getLoanChannelId()));
                if (ValidParam.isNotNull(findLoanChannelMarket)) {
                    // 存在并且状态不同则更新
                    if (!status.equals(findLoanChannelMarket.getStatus())) {
                        LoanChannelMarket loanChannelMarket = new LoanChannelMarket();
                        loanChannelMarket.setStatus(status);
                        loanChannelMarket.setId(findLoanChannelMarket.getId());
                        loanChannelMarketDao.updateLoanChannelMarket(loanChannelMarket);
                    }
                } else {
                    // 不存在则插入
                    List<LoanChannelMarket> listChannelMarket = CollUtils.newArrayList();
                    LoanChannelMarket loanChannelMarket = new LoanChannelMarket();
                    loanChannelMarket.setLoanChannelId(t.getId());
                    loanChannelMarket.setLoanMarketId(loanMarket.getId());
                    loanChannelMarket.setStatus(status);
                    loanChannelMarket.setCreateTime(DateUtils.getNowDate());
                    loanChannelMarket.setCreateBy(SecurityUtils.getUsername());
                    listChannelMarket.add(loanChannelMarket);
                    loanChannelMarketDao.batchInsert(listChannelMarket);
                }
            });
        }

        return i;
    }

    /**
     * 修改贷款超市的状态
     *
     * @param loanMarket 贷款超市
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateStatus(LoanMarket loanMarket) {

        LoanMarket po = new LoanMarket();
        po.setStatus(loanMarket.getStatus());
        po.setId(loanMarket.getId());
        return loanMarketDao.updateLoanMarket(po);
    }

    @Override
    public int remove(Long id) {
        //  设置贷超禁用状态并且设置删除状态
        LoanMarket loanMarket = new LoanMarket();
        loanMarket.setId(id);
        loanMarket.setDelStatus(1);
        loanMarket.setStatus(0);
        loanMarketDao.updateLoanMarket(loanMarket);

        //  删除所有关联该贷超的渠道
        int row = loanChannelMarketDao.deleteByMarketId(id);
        return row;
    }

    /**
     * 批量删除贷款超市
     *
     * @param ids 需要删除的贷款超市主键
     * @return 结果
     */
    @Override
    public int batchDeleteById(Long[] ids) {
        return loanMarketDao.batchDeleteById(ids);
    }

    /**
     * 删除贷款超市信息
     *
     * @param id 贷款超市主键
     * @return 结果
     */
    @Override
    public int deleteById(Long id) {
        return loanMarketDao.deleteById(id);
    }
}
